package com.bdqn.t350.ch11.controller;

import com.bdqn.t350.ch11.bean.User;
import com.bdqn.t350.ch11.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {

    private static final Logger log = LoggerFactory.getLogger(LoginController.class);

    @Resource
    UserService userService;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    private String SHIRO_LOGIN_COUNT = "shiro_login_count_"; // 登录计数



    @RequestMapping("/bootstrap")
    public String bootstrap() {
        return "bootstrap";
    }


    @GetMapping(value = "/login")
    public String login() {
        return "login";
    }

    @GetMapping(value = "/main")
    public String main() {
        return "main";
    }

/*    @PostMapping("/dologin")
    public String dologin(User user, HttpSession session) {
        User loginUser = null;
        if (user == null) {
            throw new LoginException(250, "输入的用户名为空,请重新登录");
        } else {
            loginUser = userService.selectByName(user.getUsrName());
        }
        //System.out.println(1/0);
        //说明数据库里面没有这个用户
        if (loginUser == null) {
            throw new LoginException(251, "输入的用户名在数据库中没找到");
        } else {
            //数据库中的密码和你页面传递过来的密码需要一致
            if (loginUser.getUsrPassword().equals(user.getUsrPassword())) {
                session.setAttribute("loginUser", loginUser);
                return "redirect:main";
            } else {
                System.out.println("密码错误1");
                log.info("密码错误");
                throw new LoginException(252, "密码错误");
            }
        }
    }*/


    @PostMapping("/dologin")
    public String dologin(User user, HttpSession session, Model model) {
        try {
            //构建token
            UsernamePasswordToken token =
                    new UsernamePasswordToken(user.getUsrName(), userService.encryptPassword(user.getUsrPassword()));
            //获取subject
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            //完成shiro的认证后,就可以从shiro里面获取用户
            User loginUser = (User) subject.getPrincipal();
            session.setAttribute("loginUser", loginUser);
            stringRedisTemplate.delete(SHIRO_LOGIN_COUNT + loginUser.getUsrName());
            return "redirect:main";
        } catch (UnknownAccountException e) {
            model.addAttribute("msg", "账号不存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("msg", "密码错误");
            return "login";
        } catch (DisabledAccountException e) {
            model.addAttribute("msg", "账号锁定");
            return "login";
        } catch (AuthenticationException e) {
            model.addAttribute("msg", "认证异常");
            return "login";
        }
    }

    /**
     * 退出
     *
     * @param session
     * @return
     */
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        session.removeAttribute("loginUser");
        session.invalidate();
        return "redirect:login";
    }

    /**
     * 错误页面
     *
     * @return
     */
    @RequestMapping("/error1")
    public String error1() {
        return "error";
    }

//    @RequestMapping("/500")
//    public String error500() {
//        return "500";
//    }

    @RequestMapping("/error/{status}")
    public String error(@PathVariable(value = "status") Integer status) {
        switch (status) {
            case 400:
                return "/error/400";
            case 401:
                return "/error/401";
            case 404:
                return "/error/404";
            case 500:
                return "/error/500";
            default:
                return "/error/error";
        }
    }
}
